package com.flowplan.excel.controller;

import com.flowplan.auth.util.JwtTokenUtil;
import com.flowplan.common.dto.ApiResponse;
import com.flowplan.excel.dto.ExcelParseResult;
import com.flowplan.excel.dto.ExcelPlanResponse;
import com.flowplan.excel.dto.ExcelUploadRequest;
import com.flowplan.excel.service.ExcelService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Excel处理控制器
 * 
 * @author FlowPlan Team
 */
@Slf4j
@RestController
@RequestMapping("/excel")
public class ExcelController {
    
    @Autowired
    private ExcelService excelService;
    
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    
    @Value("${jwt.header}")
    private String tokenHeader;
    
    @Value("${jwt.prefix}")
    private String tokenPrefix;
    
    /**
     * 上传Excel文件
     */
    @PostMapping("/upload")
    @PreAuthorize("hasRole('ADMIN') or hasRole('DEVELOPER') or hasRole('DEMANDER')")
    public ResponseEntity<ApiResponse<ExcelPlanResponse>> uploadExcel(
            @RequestParam("file") MultipartFile file,
            @RequestParam("projectId") Long projectId,
            @RequestParam(value = "demander", required = false) String demander,
            @RequestParam(value = "description", required = false) String description,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromToken(httpRequest);
            
            ExcelUploadRequest request = new ExcelUploadRequest();
            request.setProjectId(projectId);
            request.setDemander(demander);
            request.setDescription(description);
            
            ExcelPlanResponse response = excelService.uploadExcel(file, request, userId);
            return ResponseEntity.ok(ApiResponse.success("Excel文件上传成功", response));
        } catch (Exception e) {
            log.error("上传Excel文件失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "上传Excel文件失败: " + e.getMessage()));
        }
    }
    
    /**
     * 解析Excel文件
     */
    @PostMapping("/parse")
    public ResponseEntity<ApiResponse<ExcelParseResult>> parseExcel(
            @RequestParam("excelPlanId") Long excelPlanId) {
        try {
            ExcelPlanResponse excelPlan = excelService.getExcelPlan(excelPlanId);
            ExcelParseResult parseResult = excelService.parseExcelFile(excelPlan.getFilePath());
            return ResponseEntity.ok(ApiResponse.success("Excel文件解析成功", parseResult));
        } catch (Exception e) {
            log.error("解析Excel文件失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "解析Excel文件失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取Excel计划详情
     */
    @GetMapping("/{excelPlanId}")
    public ResponseEntity<ApiResponse<ExcelPlanResponse>> getExcelPlan(@PathVariable Long excelPlanId) {
        try {
            ExcelPlanResponse response = excelService.getExcelPlan(excelPlanId);
            return ResponseEntity.ok(ApiResponse.success("获取Excel计划详情成功", response));
        } catch (Exception e) {
            log.error("获取Excel计划详情失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "获取Excel计划详情失败: " + e.getMessage()));
        }
    }
    
    /**
     * 分页查询Excel计划列表
     */
    @GetMapping
    public ResponseEntity<ApiResponse<Page<ExcelPlanResponse>>> getExcelPlans(
            @RequestParam(required = false) Long projectId,
            @RequestParam(required = false) Long uploadUserId,
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Page<ExcelPlanResponse> response = excelService.getExcelPlans(projectId, uploadUserId, keyword, page, size);
            return ResponseEntity.ok(ApiResponse.success("查询Excel计划列表成功", response));
        } catch (Exception e) {
            log.error("查询Excel计划列表失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "查询Excel计划列表失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取项目下的Excel计划列表
     */
    @GetMapping("/project/{projectId}")
    public ResponseEntity<ApiResponse<List<ExcelPlanResponse>>> getProjectExcelPlans(@PathVariable Long projectId) {
        try {
            List<ExcelPlanResponse> response = excelService.getProjectExcelPlans(projectId);
            return ResponseEntity.ok(ApiResponse.success("获取项目Excel计划成功", response));
        } catch (Exception e) {
            log.error("获取项目Excel计划失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "获取项目Excel计划失败: " + e.getMessage()));
        }
    }
    
    /**
     * 删除Excel计划
     */
    @DeleteMapping("/{excelPlanId}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('DEVELOPER') or hasRole('DEMANDER')")
    public ResponseEntity<ApiResponse<Void>> deleteExcelPlan(
            @PathVariable Long excelPlanId,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromToken(httpRequest);
            excelService.deleteExcelPlan(excelPlanId, userId);
            return ResponseEntity.ok(ApiResponse.success("Excel计划删除成功"));
        } catch (Exception e) {
            log.error("删除Excel计划失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "删除Excel计划失败: " + e.getMessage()));
        }
    }
    
    /**
     * 下载Excel文件
     */
    @GetMapping("/{excelPlanId}/download")
    public ResponseEntity<byte[]> downloadExcel(
            @PathVariable Long excelPlanId,
            HttpServletResponse response) {
        try {
            ExcelPlanResponse excelPlan = excelService.getExcelPlan(excelPlanId);
            byte[] fileContent = excelService.downloadExcel(excelPlanId);
            
            String encodedFileName = URLEncoder.encode(excelPlan.getFileName(), StandardCharsets.UTF_8);
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", encodedFileName);
            headers.setContentLength(fileContent.length);
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(fileContent);
                    
        } catch (Exception e) {
            log.error("下载Excel文件失败: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        }
    }
    
    /**
     * 上传并解析Excel文件（一体化接口）
     */
    @PostMapping("/upload-and-parse")
    @PreAuthorize("hasRole('ADMIN') or hasRole('DEVELOPER') or hasRole('DEMANDER')")
    public ResponseEntity<ApiResponse<UploadAndParseResult>> uploadAndParseExcel(
            @RequestParam("file") MultipartFile file,
            @RequestParam("projectId") Long projectId,
            @RequestParam(value = "demander", required = false) String demander,
            @RequestParam(value = "description", required = false) String description,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromToken(httpRequest);
            
            ExcelUploadRequest request = new ExcelUploadRequest();
            request.setProjectId(projectId);
            request.setDemander(demander);
            request.setDescription(description);
            
            // 上传文件
            ExcelPlanResponse uploadResult = excelService.uploadExcel(file, request, userId);
            
            // 解析文件
            ExcelParseResult parseResult = excelService.parseExcelFile(uploadResult.getFilePath());
            
            UploadAndParseResult result = new UploadAndParseResult();
            result.setExcelPlan(uploadResult);
            result.setParseResult(parseResult);
            
            return ResponseEntity.ok(ApiResponse.success("Excel文件上传并解析成功", result));
        } catch (Exception e) {
            log.error("上传并解析Excel文件失败: {}", e.getMessage());
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(400, "上传并解析Excel文件失败: " + e.getMessage()));
        }
    }
    
    /**
     * 从Token中获取用户ID
     */
    private Long getUserIdFromToken(HttpServletRequest request) {
        String bearerToken = request.getHeader(tokenHeader);
        if (bearerToken != null && bearerToken.startsWith(tokenPrefix)) {
            String token = bearerToken.substring(tokenPrefix.length());
            return jwtTokenUtil.getUserIdFromToken(token);
        }
        throw new RuntimeException("无效的Token");
    }
    
    /**
     * 上传并解析结果内部类
     */
    public static class UploadAndParseResult {
        private ExcelPlanResponse excelPlan;
        private ExcelParseResult parseResult;
        
        public ExcelPlanResponse getExcelPlan() {
            return excelPlan;
        }
        
        public void setExcelPlan(ExcelPlanResponse excelPlan) {
            this.excelPlan = excelPlan;
        }
        
        public ExcelParseResult getParseResult() {
            return parseResult;
        }
        
        public void setParseResult(ExcelParseResult parseResult) {
            this.parseResult = parseResult;
        }
    }
}